package examples
{
	import flash.display.Sprite;
	import flash.display.Stage3D;
	import flash.display.BitmapData;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DRenderMode;
	import flash.events.Event;
	import flash.display3D.VertexBuffer3D;
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.Program3D;
	import com.adobe.utils.AGALMiniAssembler;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.textures.Texture;
	import flash.display3D.Context3DTextureFormat;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.display.Bitmap;
	import flash.geom.Matrix3D;
	import flash.utils.getDefinitionByName;
	
	/**
	 * ...
	 * @author flashk
	 */
	public class  MapStage3D extends Sprite
	{
		private var stage3D:Stage3D;
		private	var tw:uint = 2048;
		private	var th:uint = 1024;
		private	var bd2:BitmapData;
		private	var bd:BitmapData;
		private	var c3D:Context3D;
		private	var context3D:Context3D;
		private var scaNum:Number = 1300/tw;
		private var vertices: Vector.<Number>;
		private var vertBak:Vector.<Number>;
		private var vertexbuffer:VertexBuffer3D;
		private var indexbuffer:IndexBuffer3D;
		private var program:Program3D;
		private	var texture:Texture;
		private	var bp:Bitmap;
		private	var count:int = 0;
		
		[Embed(source = "GoP_1.png")]private var gop:Class;
		
		public function MapStage3D()
		{
			stage3D = this.stage.stage3Ds[0];
			stage3D.x = 0;
			stage3D.y = 0;
			//var classRef:Class = getDefinitionByName("BG") as Class;
			bd2 = new gop().bitmapData;
			bd = new BitmapData(tw,th,false,0);
			bp = new Bitmap(bd);
			
			vertices = Vector.<Number>([
				-1,-1,0, 0, scaNum,
				-1, 1, 0, 0, 0,
				1, 1, 0, scaNum, 0,
				
				1,1,0, scaNum, 0,
				1, -1, 0, scaNum, scaNum,
				-1, -1, 0, 0, scaNum]);
				
			vertBak  = vertices.slice(0);
			bd.copyPixels(bd2,new Rectangle(0,0,tw,th),new Point());
			stage3D.addEventListener("context3DCreate",initMolehill);
			stage3D.requestContext3D(Context3DRenderMode.SOFTWARE);
		}
		
		private function initMolehill(event:Event):void
		{
			c3D = stage3D.context3D;
			context3D = c3D;
			trace(c3D.driverInfo);
			c3D.configureBackBuffer(1300,700,4,false);
			vertexbuffer = context3D.createVertexBuffer(6,5);
			vertexbuffer.uploadFromVector(vertices, 0, 6);
			var indices:Vector.<uint >  = Vector.<uint > ([0,1,2,3,4,5]);
			indexbuffer = c3D.createIndexBuffer(6);
			indexbuffer.uploadFromVector(indices,0,6);
			var vertexShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler();
			vertexShaderAssembler.assemble( Context3DProgramType.VERTEX,
				"m44 op, va0, vc0\n" + 
				"mov v0, va1" 
			);
			var fragmentShaderAssembler : AGALMiniAssembler= new AGALMiniAssembler();
			fragmentShaderAssembler.assemble( Context3DProgramType.FRAGMENT,
				"tex ft1, v0, fs0 <2d, linear ,nomip> \n" +
				"mov oc, ft1"
			);
			texture = context3D.createTexture(bd2.width,bd2.height,Context3DTextureFormat.BGRA,true);
			texture.uploadFromBitmapData(bd2);
			program = context3D.createProgram();
			program.upload( vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
			this.addEventListener(Event.ENTER_FRAME,updateRender);
		}
		
		private function updateRender(event:Event):void
		{
			count++;
			if (count>130)
			{
				count = 0;
				vertices = vertBak.slice(0);
			}
			
			context3D.clear( 1, 1, 1, 1 );
			context3D.setVertexBufferAt(0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
			context3D.setVertexBufferAt(1, vertexbuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
			context3D.setTextureAt(0, texture);
			context3D.setProgram(program);
			for (var i:int =0; i<6; i++)
			{
				//x速度
				vertices[i * 5 + 3] += 0.0008;
				//y速度
				vertices[i*5+4] += 0.0006;
			};
			vertexbuffer.uploadFromVector(vertices, 0, 6);
			var m:Matrix3D = new Matrix3D();
			//m.appendRotation(getTimer()/80, Vector3D.Z_AXIS);
			context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, m, true);
			context3D.drawTriangles(indexbuffer);
			context3D.present();
		}
		
	}
	
}